package com.qhyiyun.baseweb.util;

import io.micrometer.common.util.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;

public class Sm4Util {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    //  private static String mode="SM4/ECB/PKCS7Padding";
    private static String MODE = "SM4/ECB/PKCS7Padding";

    public static void main(String[] args) throws Exception {
        byte[] key = Hex.decode("789abcdef01234560123456789abcdef"); // 16字节密钥 51f15598e126d65a1eeb09c4091dd7f5 c451379ff4602d16afd5d7fbfcdb0f32
        // byte[] key = generaterKey();
        // byte[] key=Hex.toHexString(key1).substring(0,16).getBytes(StandardCharsets.UTF_8);
        //System.out.println("key:" + Hex.toHexString(key));
        //byte[] iv = Hex.decode("fedcba9876543210fedcba9876543210"); // 16字节初始向量
        byte[] iv = new byte[0];
        //  String plainText = "Hello, SM4!";
        //  byte[] encryptedData = encrypt(plainText.getBytes(StandardCharsets.UTF_8), key, iv,null);
        String entext="6c047e958b29b1746c924a822f428a2e7067cf111eb5f6ed634f7cbf1030f21d0de44d50caeb5adc106ce22b826f7d260f0825aa28d8d66b95437ea06745beb7a328fe3b7b4e540cf30408454c42c6385fff8fb7af892849a62f01f1c8a73465053670a2ddd8eb35aeffb5e5fc5e1ff03d520e5dbdf9c90ed2f2600915a27776a328fe3b7b4e540cf30408454c42c63860a793cc7b73eb646917d23df6ddb57ba328fe3b7b4e540cf30408454c42c6384f927c5a06b04817136a4b3401566619";
        byte[] decryptedData = decrypt(Hex.decodeStrict(entext), key, null, null);
        //byte[] decryptedData = decrypt(encryptedData, key, iv,null);
        // System.out.println("Original Text: " + plainText);
        // System.out.println("Encrypted Data: " + Hex.toHexString(encryptedData) + "\n enstr-" + new String(encryptedData));
        String param = new String(decryptedData, StandardCharsets.UTF_8);
        System.out.println("Decrypted Text: " + new String(decryptedData, StandardCharsets.UTF_8));
    }

    public static String encrypt(String plainStr,String keyStr, byte[] iv, String mode) throws Exception {
        byte[] key;
        if (null == keyStr) {
            key = Hex.decode("789abcdef01234560123456789abcdef");
        }else{
            key =Hex.decode(keyStr);
        }
        byte[] plaintext=plainStr.getBytes(StandardCharsets.UTF_8);
        if (StringUtils.isEmpty(mode)) {
            mode = MODE;
        }
        Cipher cipher = Cipher.getInstance(mode, "BC");
        SecretKeySpec sm4Key = new SecretKeySpec(key, "SM4");
        //不使用偏移量
        if (null == iv || iv.length == 0) {
            cipher.init(Cipher.ENCRYPT_MODE, sm4Key);
        } else {
            IvParameterSpec ivSpec = new IvParameterSpec(iv);
            cipher.init(Cipher.ENCRYPT_MODE, sm4Key, ivSpec);
        }
        return Hex.toHexString(cipher.doFinal(plaintext));
    }

    public static byte[] decrypt(byte[] ciphertext, byte[] key, byte[] iv, String mode)  {
        if (StringUtils.isEmpty(mode)) {
            mode = MODE;
        }
        if (null == key) {
            key = Hex.decode("789abcdef01234560123456789abcdef");
        }
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance(mode, "BC");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
        SecretKeySpec sm4Key = new SecretKeySpec(key, "SM4");
        //不使用偏移量
        if (null == iv || iv.length == 0) {
            try {
                cipher.init(Cipher.DECRYPT_MODE, sm4Key);
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            }
        } else {
            IvParameterSpec ivSpec = new IvParameterSpec(iv);
            try {
                cipher.init(Cipher.DECRYPT_MODE, sm4Key, ivSpec);
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (InvalidAlgorithmParameterException e) {
                e.printStackTrace();
            }
        }
        try {
            return cipher.doFinal(ciphertext);
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] generaterKey() {
        // 创建一个 KeyGenerator 实例，并指定算法为 SM4
        KeyGenerator keyGenerator = null;
        try {
            keyGenerator = KeyGenerator.getInstance("SM4");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        // 初始化 KeyGenerator，指定密钥长度为 128 比特
        keyGenerator.init(128);
        // 生成密钥
        SecretKey secretKey = keyGenerator.generateKey();
        // 打印密钥的字节数组形式
        byte[] keyBytes = secretKey.getEncoded();
        return keyBytes;
    }
}